package org.opensuse.bs.ui.actions;

import java.io.File;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.opensuse.bs.ui.BSUIPlugin;
import org.opensuse.bs.ui.OSC;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class InitAction implements IObjectActionDelegate {
	private Object[] objs;
	
	private class NewPackageDialog extends Dialog {
		private Text title;
		private Text des;
		private IFolder pac;
		
		protected NewPackageDialog(Shell parentShell, IFolder pac) {
			super(parentShell);
			this.pac = pac;
		}
		
		protected Control createDialogArea(Composite parent) {
			Composite client = new Composite(parent, SWT.NONE);
			GridLayout layout = new GridLayout();
			client.setLayout(layout);
			layout.numColumns = 2;
			
			Label label1 = new Label(client, SWT.NONE);
			label1.setText("Title: ");
			title = new Text(client, SWT.BORDER);
			GridData gd = new GridData();
			title.setLayoutData(gd);
			gd.grabExcessHorizontalSpace = true;
			gd.horizontalAlignment = SWT.FILL;
			
			Label label2 = new Label(client, SWT.NONE);
			label2.setText("Description: ");
			des = new Text(client, SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);
			gd = new GridData();
			des.setLayoutData(gd);
			gd.grabExcessHorizontalSpace = true;
			gd.horizontalAlignment = SWT.FILL;
			gd.widthHint = 200;
			gd.heightHint = 100;
			
			return client;
		}
		
		protected  void 	okPressed() {
			final String user = BSUIPlugin.getDefault().getUser();
			final IResource project = pac.getParent();
			final String prj = project.getName();
			final String thisPkg = pac.getName();
			final String title_s = title.getText().trim();
			final String des_s = des.getText().trim();
			WorkspaceJob job = new WorkspaceJob("Adding "+thisPkg+" to BS control") {
				public IStatus runInWorkspace(IProgressMonitor monitor) {
					try {
						DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
						DocumentBuilder builder = factory.newDocumentBuilder();
						Document doc = builder.newDocument();
						
						Element pkg = doc.createElement("package");
						pkg.setAttribute("name", thisPkg);
						doc.appendChild(pkg);
						Element titlen = doc.createElement("title");
						titlen.setTextContent(title_s);
						pkg.appendChild(titlen);
						Element desn = doc.createElement("description");
						desn.setTextContent(des_s);
						pkg.appendChild(desn);
						Element person = doc.createElement("person");
						person.setAttribute("role", "maintainer");
						person.setAttribute("userid", user);
						pkg.appendChild(person);
						person = doc.createElement("person");
						person.setAttribute("role", "bugowner");
						person.setAttribute("userid", user);
						pkg.appendChild(person);
						
						File file = OSC.toFile(doc, "InitNewPackage");
						Vector<String> result = OSC.run("meta pkg "+prj+" "+thisPkg+" -F "+file.getAbsolutePath());
						file.delete();
						if(result.isEmpty()) {
							return Status.CANCEL_STATUS;
						}
						
						IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
						File dir = new File(root.getLocation().toOSString());
						String cmd = "co "+prj+" "+thisPkg;
						result = OSC.run(cmd, null, dir);
						if(result.isEmpty()) {
							return Status.CANCEL_STATUS;
						}
						project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
					}catch(Exception e) {
						e.printStackTrace();
					}
					
					final String pacPath = pac.getLocation().toOSString();
					final File dir = new File(pacPath);
					if(dir.exists() && dir.isDirectory()) {
						final String[] files = dir.list();
						if(files.length != 0) {
							Job subJob = new Job("Adding files to BS control") {
								protected IStatus run(IProgressMonitor monitor) {
									monitor.beginTask("Adding files in "+thisPkg+" to BS control", files.length);
									try {
										for(int i=0;i<files.length;i++) {
											if(monitor.isCanceled())
												return Status.CANCEL_STATUS;
											OSC.run("add "+files[i], null, dir);
											monitor.worked(1);
										}
									}finally {
										monitor.done();
									}
									return Status.OK_STATUS;
								}
							};
							subJob.schedule();
						}
					}
					return Status.OK_STATUS;
				}
			};
			job.schedule();
			close();
		}
	}
	
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		objs = new Object[0];
	}
	
	public void run(IAction action) {
		for(int i=0;i<objs.length;i++) {
			IResource resource = (IResource) objs[i];
			if(resource instanceof IFolder) {
				IFolder folder = (IFolder) resource;
				NewPackageDialog dialog =  new NewPackageDialog(null, folder);
				dialog.open();
			}else if(resource instanceof IFile) {
				final String filename = resource.getName();
				final File dir = new File(resource.getParent().getLocation().toOSString());
				Job job = new Job("Adding "+filename+" to BS control") {
					protected IStatus run(IProgressMonitor monitor) {
						OSC.run("add "+filename, null, dir);
						return Status.OK_STATUS;
					}
				};
				job.schedule();
			}
		}
	}
	
	public void selectionChanged(IAction action, ISelection selection) {
		if(selection instanceof ITreeSelection) {
			TreePath[] paths = ((ITreeSelection) selection).getPaths();
			objs = new Object[paths.length];
			for(int i=0;i<objs.length;i++) {
				objs[i] = paths[i].getLastSegment();
			}
		}
	}

}
